package main

import (
	"context"
	"errors"
	"fmt"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
	"gorm/grpc/common"
	"net"
)

// 先实现
//type UserServer interface {
//	GetById(context.Context, *common.UserRequest) (*common.UserReply, error)
//	mustEmbedUnimplementedUserServer()
//}

func main() {

	// 实现自定义认证，本质上是个拦截器或者中间件
	var authFilter grpc.UnaryServerInterceptor = AuthFilter
	//注意，不能连起来
	//authFilter = AuthFilter

	//注意，拦截器只能一个，可以在内部自行修改
	//注意，这里 grpc.UnaryInterceptor() 是个函数
	//server := grpc.NewServer(grpc.UnaryInterceptor(authFilter), grpc.UnaryInterceptor(authFilter))//panic: The unary server interceptor was already set and may not be reset.
	server := grpc.NewServer(grpc.UnaryInterceptor(authFilter))
	//注册服务，注意，这里调用的是生成的代码
	common.RegisterUserServer(server, &common.UserServerX{})
	//正常监听
	listener, err := net.Listen("tcp", ":8899")
	if err != nil {
		panic(err)
	}
	//让grpc服务与监听关联起来
	err = server.Serve(listener)
	if err != nil {
		panic(err)
	}
}

func AuthFilter(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
	incomingContext, ok := metadata.FromIncomingContext(ctx)
	if !ok {
		fmt.Println("fail to process incoming ctx")
		return nil, errors.New("fail to process incoming ctx")
	}
	u := incomingContext.Get("username")
	p := incomingContext.Get("password")

	if len(u) == 0 || len(p) == 0 {
		fmt.Println("么有用户名密码")
		return nil, errors.New("no username and/or password")
	}
	if u[0] != "admin" && p[0] != "admin" {
		fmt.Println("用户名密码不对", u, p)
		return nil, errors.New("bad username and/or password")
	}

	return handler(ctx, req) //继续处理
}
